#pragma once

#include <vector>
#include <map>
#include <set>
#include <memory>
#include <functional>

#include <QMap>

class INode;
class Scene;

template<typename T>
class QMapBuilder;
class JsonReader
{
public:
	void buildRelations();
	void pushIDBuilder(int& id);
	void pushIDVectorBuilder(std::vector<int>& ids);
	void pushIDSetBuilder(std::set<int>& ids);
	template<typename T>
	void pushQMapBuilder(QMap<int, T>& map)
	{
		QMapBuilder<T> builder;
		builder.m_map = &map;
		builders.push_back(builder);
	}

	std::map<int, int> idMap; // old Id -> new Id

	std::vector<std::function<void(JsonReader*, Scene*)>> builders;
};

class IdBuilder
{
public:
	int* pId;
	void operator()(JsonReader* pReader, Scene* scene);
};

class IdVectorBuilder
{
public:
	std::vector<int>* pIds;
	void operator()(JsonReader* pReader, Scene* scene);
};

class IdSetBuilder
{
public:
	std::set<int>* pIds;
	void operator()(JsonReader* pReader, Scene* scene);
};

template<typename T>
class QMapBuilder
{
public:
	QMap<int, T>* m_map;
	void operator()(JsonReader* pReader, Scene* scene)
	{
		QMap<int, T> tmp;
		for (auto it = m_map->begin(); it != m_map->end(); ++it)
		{
			int id = it.key();
			if (id > 0)
				id = pReader->idMap[id];
			tmp.insert(id, it.value());
		}
		*m_map = tmp;
	}
};
